texthandle: Update child visibility of handles within scrollables
authorCarlos Garnacho <carlosg@gnome.org>
Wed, 22 Jan 2014 15:41:00 +0000 (16:41 +0100)
committerCarlos Garnacho <carlosg@gnome.org>
Wed, 22 Jan 2014 16:10:07 +0000 (17:10 +0100)
If the rect a handle points to starts falling outside of the parent
scrollable allocation, the handle will be automatically hidden, and
shown again when the rectangle is visible too.

gtk/gtktexthandle.c

index 145797da58c80804ef47bce0f7f95c07be43f8f8..0f05d5aa82fa9a77654ce9c210b9828bc3ae01c9 100644 (file)
@@ -251,6 +251,40 @@ _gtk_text_handle_ensure_widget (GtkTextHandle         *handle,
   return priv->windows[pos].widget;
 }
 
+static void
+_handle_update_child_visible (GtkTextHandle         *handle,
+                              GtkTextHandlePosition  pos)
+{
+  HandleWindow *handle_window;
+  GtkTextHandlePrivate *priv;
+  cairo_rectangle_int_t rect;
+  GtkAllocation allocation;
+  GtkWidget *parent;
+
+  priv = handle->priv;
+  handle_window = &priv->windows[pos];
+
+  if (!priv->parent_scrollable)
+    {
+      gtk_widget_set_child_visible (handle_window->widget, TRUE);
+      return;
+    }
+
+  parent = gtk_widget_get_parent (GTK_WIDGET (priv->parent_scrollable));
+  rect = handle_window->pointing_to;
+
+  gtk_widget_translate_coordinates (priv->parent, parent,
+                                    rect.x, rect.y, &rect.x, &rect.y);
+
+  gtk_widget_get_allocation (GTK_WIDGET (parent), &allocation);
+
+  if (rect.x < 0 || rect.x + rect.width > allocation.width ||
+      rect.y < 0 || rect.y + rect.height > allocation.height)
+    gtk_widget_set_child_visible (handle_window->widget, FALSE);
+  else
+    gtk_widget_set_child_visible (handle_window->widget, TRUE);
+}
+
 static void
 _gtk_text_handle_update (GtkTextHandle         *handle,
                          GtkTextHandlePosition  pos)
@@ -273,9 +307,13 @@ _gtk_text_handle_update (GtkTextHandle         *handle,
       GtkWidget *window;
 
       _gtk_text_handle_ensure_widget (handle, pos);
+      _gtk_text_handle_get_size (handle, &width, &height);
       rect.x = handle_window->pointing_to.x;
       rect.y = handle_window->pointing_to.y;
-      _gtk_text_handle_get_size (handle, &width, &height);
+      rect.width = width;
+      rect.height = 0;
+
+      _handle_update_child_visible (handle, pos);
 
       window = gtk_widget_get_parent (handle_window->widget);
       gtk_widget_translate_coordinates (priv->parent, window,
@@ -290,8 +328,6 @@ _gtk_text_handle_update (GtkTextHandle         *handle,
         }
 
       height += handle_window->pointing_to.height;
-      rect.width = width;
-      rect.height = 0;
       rect.x -= rect.width / 2;
 
       gtk_widget_set_size_request (handle_window->widget, width, height);